import math
import select
import os
import shutil
import maya.cmds as cmds
import maya.mel as mel


def asGetImConvertCmd():
	imConvertCmd = "imconvert"
	mayaLocation = os.getenv("MAYA_LOCATION")
	if os.path.exists(mayaLocation + "/bin/magick.exe") or os.path.exists(mayaLocation + "/bin/magick"):
		imConvertCmd = "magick"
	return imConvertCmd


def asGetTempDirectory():
	tempDirectory = os.environ['TEMP']
	folders = []
	if "~" in tempDirectory:
		folders = tempDirectory.split("/")
		tempDirectory = ""
		for i in range(len(folders)):
			if "~" in folders[i]:
				folders[i] = os.environ['USERNAME']
			tempDirectory += folders[i]
			if i < len(folders) - 1:
				tempDirectory += "/"
	return tempDirectory
def asAutoLipSyncPhonemeMapping(phone):
	phone = phone.upper()
	phoneme = ""
	if phone == "EY1":
		phoneme = "aaa"
	if phone == "Z":
		phoneme = "sss"
	if phone == "B":
		phoneme = "mbp"
	if phone == "AA2":
		phoneme = "aaa"
	if phone == "D":
		phoneme = "lntd"
	if phone == "IY0":
		phoneme = "tth"
	if phone == "K":
		phoneme = "gk"
	if phone == "AO2":
		phoneme = "ohh"
	if phone=="R"	:
		phoneme="rrr"
	if phone=="T"	:
		phoneme="lntd"
	if phone=="G"	:
		phoneme="gk"
	if phone=="AH0"  :
		phoneme="ahh"
	if phone=="OY1"  :
		phoneme="ohh"
	if phone=="N"	:
		phoneme="lntd"
	if phone=="L"	:
		phoneme="lntd"
	if phone=="M"	:
		phoneme="mbp"
	if phone=="AY1"  :
		phoneme="ahh"
	if phone=="OW2"  :
		phoneme="ohh"
	if phone=="S"	:
		phoneme="sss"
	if phone=="P"	:
		phoneme="mbp"
	if phone=="EH2"  :
		phoneme="eh"
	if phone=="IY1"  :
		phoneme="iee"
	if phone=="AY2"  :
		phoneme="aaa"
	if phone=="OW1"  :
		phoneme="ohh"
	if phone=="ER0"  :
		phoneme="schwa"
	if phone=="UW1"  :
		phoneme="ohh"
	if phone=="W"	:
		phoneme="www"
	if phone=="DH"   :
		phoneme="lntd"
	if phone=="JH"   :
		phoneme="ssh"
	if phone=="IH1"  :
		phoneme="iee"
	if phone=="IH0"  :
		phoneme="iee"
	if phone=="NG"   :
		phoneme="gk"
	if phone=="IH2"  :
		phoneme="eh"
	if phone=="V"	:
		phoneme="schwa"
	if phone=="AA1"  :
		phoneme="ohh"
	if phone=="TH"   :
		phoneme="lntd"
	if phone=="ZH"   :
		phoneme="ssh"
	if phone=="AE2"  :
		phoneme="aaa"
	if phone=="SH"   :
		phoneme="ssh"
	if phone=="EH1"  :
		phoneme="eh"
	if phone=="AA0"  :
		phoneme="aaa"
	if phone=="F"	:
		phoneme="fff"
	if phone=="AW1"  :
		phoneme="www"
	if phone=="AE1"  :
		phoneme="aaa"
	if phone=="OW0"  :
		phoneme="ohh"
	if phone=="AW2"  :
		phoneme="aaa"
	if phone=="EY2"  :
		phoneme="eh"
	if phone=="EY0"  :
		phoneme="aaa"
	if phone=="AE0"  :
		phoneme="aaa"
	if phone=="IY2"  :
		phoneme="iee"
	if phone=="CH"   :
		phoneme="ssh"
	if phone=="ER1"  :
		phoneme="ahh"
	if phone=="EH0"  :
		phoneme="ahh"
	if phone=="UW2"  :
		phoneme="ohh"
	if phone=="AH1"  :
		phoneme="ohh"
	if phone=="HH"   :
		phoneme="schwa"
	if phone=="AH2"  :
		phoneme="ahh"
	if phone=="AO0"  :
		phoneme="ahh"
	if phone=="OY2"  :
		phoneme="ohh"
	if phone=="OY0"  :
		phoneme="ohh"
	if phone=="UH1"  :
		phoneme="ohh"
	if phone=="AO1"  :
		phoneme="ohh"
	if phone=="UW0"  :
		phoneme="ohh"
	if phone=="Y"	:
		phoneme="uuu"
	if phone=="AW0"  :
		phoneme="aaa"
	if phone=="AY0"  :
		phoneme="ahh"
	if phone=="ER2"  :
		phoneme="ohh"
	if phone=="UH0"  :
		phoneme="uuu"
	if phone=="UH2":  
		phoneme="ohh"
	return phoneme

nameSpace = "A10_C0350WJY_RIG:"
gMainProgressBar = mel.eval('$tmpVar=$gMainProgressBar')
gPlayBackSlider = "PlayBackSlider"
gCurrentTimeCmdValueTable = []
segmentReplacing = 0
aPlayBackSliderPython = mel.eval('$tmpVar=$gPlayBackSlider')  # 获取时间轴信息
timeRangeArray = cmds.timeControl(aPlayBackSliderPython , q = True , rangeArray = 1)
fps = currentTimeUnitToFPS()
if fps < 1:
	fps = 1
nonLatin = cmds.checkBox("asAutoLipSyncNonLatinCheckBox" , q = True , v = 1)  # False
wordsSection , phonesSection , fileId = 0 , 0 , 0
autoBlink = cmds.checkBox("asAutoLipSyncBlinkCheckBox" , q = True , v = 1)  # True
autoGlimpse = cmds.checkBox("asAutoLipSyncGlimpseCheckBox" , q = True , v = 1)  # True
autoEyeBrows = cmds.checkBox("asAutoLipSyncEyeBrowsCheckBox" , q = True , v = 1)  # True
autoHead = cmds.checkBox("asAutoLipSyncHeadCheckBox" , q = True , v = 1)  # True
lastKeyFrameNr , nextBlinkTriggFrameNr , nextGlipseTriggFrameNr , nextHeadTriggFrameNr , wordNr = 0 , 0 , 0 , 0 , 0
if not cmds.objExists(nameSpace + "FKHead_M"):
	autoHead = 0
prePhoneTime = cmds.floatField("asAutoLipSyncPhonemeInFloatField" , q = True , v = 1) * fps
postPhoneTime = cmds.floatField("asAutoLipSyncPhonemeOutFloatField" , q = True , v = 1) * fps
sequenceStart = -1
sequenceEnd = -1
wordSpace = 0.25  # 0.25*$fps
scale = 1.5
xMin , xMax , segRepOffset , keyValue , previousKeyTime = 0 , 0 , 0 , 0 , 0
wordStarts , wordEnds , phoneStarts , phoneEnds , bb , keyTimes , pos , pos1 , pos2 = [] , [] , [] , [] , [] , [] , [] , [] , []
aligner = cmds.text("asAutoLipSyncAlignerText" , q = True , l = 1)
tempDir = asGetTempDirectory() + "/AdvancedSkeleton/autoLipSync/"
textGridFile = tempDir + "output/align.TextGrid"
nextLine , para , value , pythonCmd , fileRead , font , imConvertCmdLine = "" , "" , "" , "" , "" , "" , ""
imConvertCmd = asGetImConvertCmd()
tempString , words , phones , missingPhoneParts , letters , deleteObjs , texts , chars = [] , [] , [] , [] , [] , [] , [] , []
currentTimeUnit = cmds.currentUnit(q = True , t = True)
audioNode = cmds.timeControl(aPlayBackSliderPython , q = True , s = 1)
languageMenuValue = cmds.optionMenu("asAutoLipSyncLanguageOptionMenu" , q = True , v = 1)
language = languageMenuValue.lower()
offset = cmds.getAttr(audioNode + ".offset") / fps

if not cmds.objExists(nameSpace + "ctrlPhonemes_M"):
	cmds.error(nameSpace + "ctrlPhonemes_M not found")

if cmds.objExists(nameSpace + "FaceFitSkeletonHeightShape"):
	pos1 = cmds.xform(nameSpace + "FaceFitSkeletonHeightShape.cv[5]" , q = True , ws = True , t = 1)
	pos2 = cmds.xform(nameSpace + "FaceFitSkeletonShape.cv[5]" , q = True , ws = True , t = 1)
	scale = pos1[1] - pos2[1]

if (timeRangeArray[1] - timeRangeArray[0]) > 1 and cmds.objExists(nameSpace + "subTitles"):
	segmentReplacing = 1

if segmentReplacing:
	cmds.select(cl = True)
	pos = cmds.xform(nameSpace + "subTitlesArrowShape.cv[3]" , q = True , ws = True , t = 1)
	texts = cmds.listRelatives(nameSpace + "subTitlesRoller" , c = 1 , type = "transform")
	cmds.currentTime(timeRangeArray[0])
	previousKeyTime = cmds.findKeyframe(nameSpace + "subTitlesRoller.tx" , q = 1 , which = "previous" , time = 1)

	for i in range(len(texts)):
		chars = cmds.listRelatives(c = True , type = "transform" , ad = True , f = texts[i])
		print
		chars
		if nonLatin:
			chars[0] = texts[i]
		for y in range(len(chars)):
			if (cmds.getAttr(t = (cmds.getAttr(previousKeyTime , (nameSpace + "subTitlesRoller.tx")) * -1 , cmds.getAttr((texts[i] + ".tx"))))):
				cmds.select(add = True , objects = texts[i])

	if len(cmds.ls(selection = True)) > 0:
		cmds.delete()

	if cmds.objExists(nameSpace + "subTitlesRoller"):
		cmds.cutKey(time = (timeRangeArray[0] + ":99999") , attribute = "translateX" , option = "keys" , clear = True)
	cmds.cutKey(time = (timeRangeArray[0] + ":99999") , option = "keys" , clear = True , attribute = (nameSpace + "ctrlPhonemes_M"))

# if not mel.eval('stringArrayCount("sec", %s)'%(gCurrentTimeCmdValueTable)) and mel.eval('exists( workingTimeUtil)'):
#	cmds.optionVar(iv=("hideNoFPSFramerate", 0))
#	cmds.evalDeferred("source workingTimeUtil")

cmds.currentUnit(t = "sec")
# cmds.evalDeferred('catchQuiet(\'currentUnit -t {}\')'.format(currentTimeUnit))

if cmds.currentUnit(q = True , t = True) == "sec":
	cmds.currentUnit(t = "film")
if segmentReplacing:
	segRepOffset = cmds.currentTime(q = 1)
if segmentReplacing:
	if cmds.objExists("subTitles_parentConstraint1"):
		cmds.delete("subTitles_parentConstraint1")
	if cmds.objExists(nameSpace + "subTitles"):
		cmds.xform(ws = True , t = [0 , 0 , 0] , ro = [0 , 0 , 0] , s = [1 , 1 , 1] , object = (nameSpace + "subTitles"))
else:
	deleteObjs = [nameSpace + "subTitles" , nameSpace + "subTitlesExp" , nameSpace + "subTitlesBox" , nameSpace + "subTitlesArrow" , nameSpace + "subTitlesBoxMPD"]
	for i in range(len(deleteObjs)):
		if cmds.objExists(deleteObjs[i]):
			cmds.delete(deleteObjs[i])
	cmds.createNode("transform" , name = nameSpace + "subTitles")  # createNode -n ($nameSpace+"subTitles") transform;
	cmds.createNode("transform" , name = nameSpace + "subTitlesRoller" , parent = nameSpace + "subTitles")  # createNode -n ($nameSpace+"subTitlesRoller") -p ($nameSpace+"subTitles") transform;
	tempString = cmds.curve(d = 1 , p = [(-4 , 1.25 , 0) , (-4 , -0.5 , 0) , (4 , -0.5 , 0) , (4 , 1.25 , 0) , (-4 , 1.25 , 0)] , k = [0 , 1 , 2 , 3 , 4])  # $tempString[0]=`curve -d 1 -p -4 1.25 0 -p -4 -0.5 0 -p 4 -0.5 0 -p 4 1.25 0 -p -4 1.25 0 -k 0 -k 1 -k 2 -k 3 -k 4`;
	cmds.rename(tempString , nameSpace + "subTitlesBox")  # rename $tempString[0] ($nameSpace+"subTitlesBox");
	cmds.setAttr(nameSpace + "subTitlesBoxShape.overrideEnabled" , 1)  # setAttr ($nameSpace+"subTitlesBoxShape.overrideEnabled") 1;
	cmds.setAttr(nameSpace + "subTitlesBoxShape.overrideColor" , 13)
	tempString = cmds.curve(d = 1 , p = [(0 , 0.65 , 0) , (0.127 , 1.2 , 0) , (-0.127 , 1.2 , 0) , (0 , 0.65 , 0)] , k = [0 , 1 , 2 , 3])  # $tempString[0]=`curve -d 1 -p 0 0.65 0 -p 0.127 1.2 0 -p -0.127 1.2 0 -p 0 0.65 0 -k 0 -k 1 -k 2 -k 3`;
	cmds.parent(nameSpace + "subTitlesBox" , nameSpace + "subTitles")  # parent ($nameSpace+"subTitlesBox") ($nameSpace+"subTitles");
	cmds.addAttr(nameSpace + "subTitlesBox" , k = 1 , ln = "textVisCenter" , at = "double" , dv = 4.5)  # addAttr -k 1 -ln textVisCenter -at double -dv 4.5 ($nameSpace+"subTitlesBox");
	cmds.addAttr(nameSpace + "subTitlesBox" , k = 1 , ln = "textVisLenght" , at = "double" , dv = 8)  # addAttr -k 1 -ln textVisLenght -at double -dv 8 ($nameSpace+"subTitlesBox");
	cmds.createNode("multiplyDivide" , n = nameSpace + "subTitlesBoxMPD")  # createNode -n ($nameSpace+"subTitlesBoxMPD") multiplyDivide;
	cmds.connectAttr(nameSpace + "subTitlesBox.sx" , nameSpace + "subTitlesBoxMPD.input1X")  # connectAttr ($nameSpace+"subTitlesBox.sx") ($nameSpace+"subTitlesBoxMPD.input1X");
	cmds.connectAttr(nameSpace + "subTitlesBox.sx" , nameSpace + "subTitlesBoxMPD.input1Y")  # connectAttr ($nameSpace+"subTitlesBox.sx") ($nameSpace+"subTitlesBoxMPD.input1Y");
	cmds.setAttr(nameSpace + "subTitlesBoxMPD.input2" , 4 , 8 , 0 , type = "float3")  # setAttr ($nameSpace+"subTitlesBoxMPD.input2") -type float3 4 8 0;
	cmds.connectAttr(nameSpace + "subTitlesBoxMPD.outputX" , nameSpace + "subTitlesBox.textVisCenter")  # connectAttr ($nameSpace+"subTitlesBoxMPD.outputX") ($nameSpace+"subTitlesBox.textVisCenter");
	cmds.connectAttr(nameSpace + "subTitlesBoxMPD.outputY" , nameSpace + "subTitlesBox.textVisLenght")  # connectAttr ($nameSpace+"subTitlesBoxMPD.outputY") ($nameSpace+"subTitlesBox.textVisLenght");
	cmds.rename(tempString , nameSpace + "subTitlesArrow")  # rename $tempString[0] ($nameSpace+"subTitlesArrow");
	cmds.setAttr(nameSpace + "subTitlesArrowShape.overrideEnabled" , 1)  # setAttr ($nameSpace+"subTitlesArrowShape.overrideEnabled") 1;
	cmds.setAttr(nameSpace + "subTitlesArrowShape.overrideColor" , 13)  # setAttr ($nameSpace+"subTitlesArrowShape.overrideColor") 13;
	cmds.parent(nameSpace + "subTitlesArrowShape" , nameSpace + "subTitlesBox" , add = 1 , s = 1)  # parent -add -s ($nameSpace+"subTitlesArrowShape") ($nameSpace+"subTitlesBox");
	cmds.delete(nameSpace + "subTitlesArrow")  # delete ($nameSpace+"subTitlesArrow");
	tempString = cmds.listConnections(nameSpace + "ctrlPhonemes_M" , s = 1 , d = 0 , type = "animCurve")  # $tempString=`listConnections -s 1 -d 0 -type animCurve ($nameSpace+"ctrlPhonemes_M")`;
	print(tempString)
	# cmds.parentConstraint(nameSpace + "ctrlBox" , nameSpace + "subTitlesRoller" , mo = True)
	if tempString:  # if (size($tempString)) delete $tempString;
		cmds.delete(tempString)

		tempString = cmds.listAttr(nameSpace + "ctrlPhonemes_M" , ud = True)
		for attr in tempString:
			if not cmds.getAttr(nameSpace + "ctrlPhonemes_M." + attr , lock = True):
				cmds.setAttr(nameSpace + "ctrlPhonemes_M." + attr , 0)
		if cmds.attributeQuery("jaw" , node = nameSpace + "ctrlPhonemes_M" , exists = True):
			cmds.setAttr(nameSpace + "ctrlPhonemes_M.jaw" , 0.25)
			cmds.setAttr(nameSpace + "ctrlPhonemes_M.lip" , 0.25)
			if cmds.objExists("asFaceBS"):
				cmds.setAttr(nameSpace + "ctrlPhonemes_M.jaw" , 1)
				cmds.setAttr(nameSpace + "ctrlPhonemes_M.lip" , 1)

with open(textGridFile , 'r') as fileId:
	for nextLine in fileId:
		line = nextLine.strip()
		if line:
			tempString = line.split(" = ")
			if len(tempString) >= 2:
				para = tempString[0]
				value = tempString[1]
				# print(para)
				# print(value)

				if sequenceStart == -1 and para == "xmin":
					sequenceStart = float(value) * fps

				if sequenceEnd == -1 and para == "xmax":
					sequenceEnd = float(value) * fps

				if para == "name":
					if value == "\"words\"":
						wordsSection = 1
					if value == "\"phones\"":
						phonesSection = 1
						wordsSection = 0

				if para == "xmin":
					xMin = float(value)
				if para == "xmax":
					xMax = float(value)

				if wordsSection and para == "text":
					tempString[0] = value.replace("\"" , "")
					if tempString[0] != "":
						words.append(tempString[0])
						wordStarts.append((xMin + segRepOffset + offset) * fps)
						wordEnds.append((xMax + segRepOffset + offset) * fps)

				if phonesSection and para == "text":
					tempString[0] = value.replace("\"" , "")
					if tempString[0] != "":
						phones.append(tempString[0])
						phoneStarts.append((xMin + segRepOffset + offset) * fps)
						phoneEnds.append((xMax + segRepOffset + offset) * fps)

fileId.close()

for i in range(len(words)):
	if words[i] == "<unk>":
		words[i] = "***"
if not segmentReplacing:
	cmds.playbackOptions(min = (sequenceStart + offset) , ast = (sequenceStart + offset) , aet = (sequenceEnd + offset) , max = (sequenceEnd + offset))

# setKeyframe command
cmds.setKeyframe(nameSpace + "subTitlesRoller" , at = "tx" , v = 0 , t = 0 , itt = "linear" , ott = "linear")

# for loop
wordNr = 0
for i in range(9999):
	if not cmds.objExists(nameSpace + "text" + str(i)):
		break
	wordNr = i
if nonLatin:
	if not os.path.exists(tempDir + "render"):
		os.makedirs(tempDir + "render")
	wordsSection = 0
	# wordNr = wordNr
	searchfile = open(textGridFile , 'r')
	for line in searchfile:
		if line.find('name = \"words\"') != -1:
			wordsSection = 1
		if line.find('name = \"phones\"') != -1:
			wordsSection = 0
		if wordsSection == 1:
			if line.find('text = ') != -1:
				word = line.split()[2].replace('\"' , '')
				if word == '':
					continue
				tempDir + "render/word" + str(wordNr) + ".txt"
				wordFile = open(tempDir + "render/word" + str(wordNr) + ".txt" , 'w')
				wordFile.write(word)
				wordFile.close()
				wordNr = wordNr + 1
	searchfile.close()

if nonLatin:
	cmds.progressBar(gMainProgressBar , e = True , ep = 1)
cmds.progressBar(gMainProgressBar , e = True , st = "Reading Data" , bp = 1 , ii = 1 , min = 0 , max = (len(words) + 1))
for i in range(len(words)):
	cmds.progressBar(gMainProgressBar , e = True , s = 1)
	if cmds.progressBar(gMainProgressBar , q = True , ic = 1):
		cmds.error("Interrupted")
	cmds.currentTime(wordStarts[i])
	if nonLatin:
		font = "arial"
	if language == "thai":
		font = "tahoma"
	if language == "korean":
		font = "Malgun-Gothic"
	imConvertCmdLine = imConvertCmd + " -background black -fill white -font " + font + " -pointsize 72 label:@" + tempDir + "render/word" + str(wordNr) + ".txt " + tempDir + "render/word" + str(wordNr) + ".png"
	os.system(imConvertCmdLine)
	tempString = cmds.ls((nameSpace + "text*" + str(wordNr)))
	for y in range(len(tempString)):
		if cmds.objExists(tempString[y]):
			cmds.delete(tempString[y])
		cmds.polyPlane(n = nameSpace + "text" + str(wordNr) , w = 1 , h = 1 , sx = 1 , sy = 1 , ax = [0 , 0 , 1] , cuv = 2 , ch = 0)
		cmds.shadingNode("surfaceShader",n = nameSpace + "textShader" + str(wordNr) , asShader = 1)
		cmds.sets(renderable = True , noSurfaceShader = True , empty = True , name = (nameSpace + "textSG" + str(wordNr)))
		cmds.connectAttr(nameSpace + "textShader" + str(wordNr) + ".outColor" , nameSpace + "textSG" + str(wordNr) + ".surfaceShader" ,f=1)
		cmds.sets(nameSpace + "text" + str(wordNr) , e = True , forceElement = nameSpace + "textSG" + str(wordNr))
		cmds.createNode("file" , n = nameSpace + "textFile" + str(wordNr))
		cmds.connectAttr(nameSpace + "textFile" + str(wordNr) + ".outColor" , nameSpace + "textShader" + str(wordNr) + ".outColor" , force = 1)
		cmds.setAttr((nameSpace + "textFile" + str(wordNr) + ".fileTextureName") , (tempDir + "render/word" + str(wordNr) + ".png") , type = "string")
		cmds.move(0.5 , 0 , 0 , nameSpace + "text" + str(wordNr) + ".vtx[0:99]" , r = True , ws = True , wd = 1)
		cmds.scale(len(words[i]) / 2.25 , 1 , 1 , nameSpace + "text" + str(wordNr) + ".vtx[0:99]" , r = True , p = [0 , 0 , 0])
	else:
		tempString = cmds.textCurves( f = "Times New Roman|wt:50|sz:28" , t = words[i])
		cmds.delete(cmds.ls(type = "makeTextCurves"))
		cmds.rename(tempString[0] , nameSpace + "text" + str(wordNr))
	cmds.setAttr(nameSpace + "text" + str(wordNr) + ".tx" , wordSpace)
	cmds.parent(nameSpace + "text" + str(wordNr) , nameSpace + "subTitlesRoller")
	cmds.setKeyframe(nameSpace + "subTitlesRoller.tx" , itt = "linear" , ott = "linear" , t = wordStarts[i] , v = (cmds.getAttr((nameSpace + "subTitlesRoller.tx")) - wordSpace))
	bb = cmds.xform(nameSpace + "text" + str(wordNr) , q = 1 , ws = 1 , bb = 1)
	keyValue = cmds.getAttr(nameSpace + "subTitlesRoller.tx") - (float(bb[0]) + float(bb[3]))
	cmds.setKeyframe(nameSpace + "subTitlesRoller.tx" , itt = "linear" , ott = "linear" , t = wordEnds[i] , v = keyValue)
	wordNr += 1
for i in range(len(phones)):
	if (phones[i] == "sil" or phones[i] == "sp" or phones[i] == "spn"):
		continue
	# if (language == "english"):
	phoneme = asAutoLipSyncPhonemeMapping(phones[i])
	# else:
	#	 phoneme = substring(language, 0, 3) + "_" + asPhonemeTranslate(phones[i], 0)
	if phoneme == "" or not cmds.attributeQuery(phoneme,n = nameSpace + "ctrlPhonemes_M" ,exists = True):
		if not phoneme in missingPhoneParts:
			missingPhoneParts.append("Phoneme:\"" + phoneme + "\", from the phone:	\"" + phones[i] + "\"")
		continue
	cmds.setKeyframe(nameSpace + "ctrlPhonemes_M." + phoneme, v = 0 , t = phoneStarts[i] - prePhoneTime )
	cmds.setKeyframe(nameSpace + "ctrlPhonemes_M." + phoneme,v = 10 , t = (phoneStarts[i] + phoneEnds[i]) / 2.0 )
	cmds.setKeyframe(nameSpace + "ctrlPhonemes_M." + phoneme,v = 0 , t = phoneEnds[i] + postPhoneTime)

if len(missingPhoneParts) > 0:
	print("Found the following phonemes, that are not mapped to the current FaceSetup:")
	print(missingPhoneParts)
cmds.progressBar(gMainProgressBar,e = True , ep = 1)
cmds.currentTime(0)

#if not cmds.currentUnit(q = True , t = True) == "sec":
#	cmds.currentUnit(t = currentTimeUnit)

cmds.currentTime(0)
tempString = cmds.listRelatives(ad = True , type = "transform" , f = (nameSpace + "subTitlesRoller"))
for i in range(len(tempString)):
	if not tempString[i].startswith("Char_") and not nonLatin:
		continue
	letters.append(tempString[i])

bb = cmds.xform(nameSpace + "subTitlesBox",q = True , ws = True , bb = 1)
boxWidth = (bb[3] - bb[0]) / cmds.getAttr(nameSpace + "subTitles.sx")

if nameSpace != "" and cmds.objExists("subTitlesRoller_translateX"):
	cmds.rename("subTitlesRoller_translateX" , nameSpace + "subTitlesRoller_translateX")

keyTimes = cmds.keyframe(nameSpace + "subTitlesRoller_translateX",q = True , tc =1)
lastKeyFrameNr = keyTimes[-1]
cmds.progressBar(gMainProgressBar,e = True , st = "Animating text visibility" , bp = True , min = 0 , max = lastKeyFrameNr + 1) 
#letters = cmds.sort(letters)

for y in range(len(letters)):
	if cmds.objExists((letters[y] + "PMA")):
		continue
	cmds.createNode("plusMinusAverage" , n = (letters[y] + "PMA"))
	cmds.connectAttr((nameSpace + "subTitlesRoller_translateX.output") , (letters[y] + "PMA.input1D[1]") , f = True)
	cmds.connectAttr((nameSpace + "subTitlesBox.textVisCenter") , (letters[y] + "PMA.input1D[2]") , f = True)
	bb = cmds.xform(q = True , ws = True , bb = letters[y])
	cmds.setAttr((letters[y] + "PMA.input1D[0]") , (bb[0] + 0.5))
	cmds.createNode("clamp" , n = (letters[y] + "Clamp"))
	cmds.connectAttr((letters[y] + "PMA.output1D") , (letters[y] + "Clamp.inputR") , f = True)
	cmds.setAttr((letters[y] + "Clamp.maxR") , 1000)
	cmds.createNode("condition" , n = (letters[y] + "Condition"))
	cmds.setAttr((letters[y] + "Condition.operation") , 2)
	cmds.connectAttr((letters[y] + "Clamp.outputR") , (letters[y] + "Condition.firstTerm") , f = True)
	cmds.connectAttr((letters[y] + "Clamp.outputR") , (letters[y] + "Condition.colorIfFalseR") , f = True)
	cmds.connectAttr((nameSpace + "subTitlesBox.textVisLenght") , (letters[y] + "Condition.secondTerm") , f = True)
	cmds.connectAttr((letters[y] + "Condition.outColorR") , (letters[y] + ".v") , f = True)

bb = cmds.xform(q = True , ws = True , bb = (nameSpace + "subTitles"))
cmds.setAttr((nameSpace + "subTitles.s") , scale / 10.0 , scale / 10.0 , scale / 10.0 , type = "float3")
cmds.xform(ws = True , t = [bb[3] + bb3[3] * 1.2 , bb2[1] , bb[5]] , object = (nameSpace + "subTitles"))
cmds.parentConstraint((nameSpace + "ctrlBox") , (nameSpace + "subTitles") , mo = True)

if segmentReplacing:
	cmds.select(r = (nameSpace + "subTitles"))
	cmds.currentTime(timeRangeArray[0])
	cmds.dgdirty(a = True)
	return

if autoBlink:
	tempString = cmds.listConnections(s = True , d = False , type = "animCurve" , shapes = True , (nameSpace + "ctrlEye_R") , (nameSpace + "ctrlEye_L"))
	if len(tempString) > 0:
		cmds.delete(tempString)

if autoGlimpse:
	tempString = cmds.listConnections(s = True , d = False , type = "animCurve" , shapes = True , (nameSpace + "Eye_R") , (nameSpace + "Eye_L"))
	if len(tempString) > 0:
		cmds.delete(tempString)

if autoHead:
	tempString = cmds.listConnections(s = True , d = False , type = "animCurve" , (nameSpace + "FKHead_M"))
	if len(tempString) > 0:
		cmds.delete(tempString)

if autoBlink:
	tempString = cmds.listConnections(s = True , d = False , type = "animCurve" , shapes = True , (nameSpace + "ctrlEye_R") , (nameSpace + "ctrlEye_L"))
	if len(tempString) > 0:
		cmds.delete(tempString)

if autoHead:
	cmds.setAttr((nameSpace + "AimEye_M.follow") , 0)

nextBlinkTriggFrameNr = keyTimes[0] + random.randint(25 , 40)
nextGlipseTriggFrameNr = keyTimes[0] + random.randint(25 , 40)
nextHeadTriggFrameNr = keyTimes[0] + random.randint(80 , 100)

for i in range(1 , int(cmds.playbackOptions(q = True , max = True))):
	if i < keyTimes[0]:
		continue
	if autoBlink and i == nextBlinkTriggFrameNr:
		nextBlinkTriggFrameNr = i + random.randint(50 , 250)
		cmds.setKeyframe(t = i , v = 1.5 , attribute = (nameSpace + "ctrlEye_L.blink") , (nameSpace + "ctrlEye_R.blink"))
		cmds.setKeyframe(t = (i + 1) , v = 10 , attribute = (nameSpace + "ctrlEye_L.blink") , (nameSpace + "ctrlEye_R.blink"))
		cmds.setKeyframe(t = (i + 3) , v = 10 , attribute = (nameSpace + "ctrlEye_L.blink") , (nameSpace + "ctrlEye_R.blink"))
		cmds.setKeyframe(t = (i + 6) , v = 1.5 , attribute = (nameSpace + "ctrlEye_L.blink") , (nameSpace + "ctrlEye_R.blink"))
